From d8dfab4a3552552aa7be3c0164f0404e1bcfd43a Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 28 Nov 2006 13:53:12 +0000 Subject: [PATCH] [HVMLOADER] acpi: Implement an acpi_rsdp_get() function that searches for the RSDP in memory (up to the BIOS) rather than calculating its start address. Recent changes seem to have moved the RSDP to another location in memory so that I received 'BAD RSPD signature' messages. I have also fixed some other possible issues related to return codes and alignment of ACPI entries. Signed-off-by: Stefan Berger --- tools/firmware/hvmloader/acpi_utils.c | 61 +++++++++++++++++++++------ 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/tools/firmware/hvmloader/acpi_utils.c b/tools/firmware/hvmloader/acpi_utils.c index 5dd74365c9..5fd9847d4e 100644 --- a/tools/firmware/hvmloader/acpi_utils.c +++ b/tools/firmware/hvmloader/acpi_utils.c @@ -85,7 +85,8 @@ static void acpi_tpm_tis_probe(unsigned char *acpi_start, return; /* legacy systems need an RSDT entry */ - acpi_rsdt_add_entry_pointer(acpi_start, addr); + if ( acpi_rsdt_add_entry_pointer(acpi_start, addr) != 1 ) + return; /* add ACPI TCPA table */ addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, @@ -108,7 +109,8 @@ static void acpi_tpm_tis_probe(unsigned char *acpi_start, tcpa->header.length); } - acpi_rsdt_add_entry_pointer(acpi_start, addr); + if ( acpi_rsdt_add_entry_pointer(acpi_start, addr) != 1 ) + return; } @@ -125,17 +127,51 @@ void acpi_update(unsigned char *acpi_start, } +/* + * Search for the RSDP in memory below the BIOS + */ +struct acpi_20_rsdp *acpi_rsdp_get(unsigned char *acpi_start) +{ + int offset = 0; + int found = 0; + static int displayed = 0; + struct acpi_20_rsdp *rsdp; + + while ( &acpi_start[offset] < (unsigned char *)0xf0000 ) + { + rsdp = (struct acpi_20_rsdp *)&acpi_start[offset]; + if ( rsdp->signature == ACPI_2_0_RSDP_SIGNATURE ) + { + found = 1; + break; + } + offset += 0x10; + } + + if ( !found ) + rsdp = NULL; + + if ( !displayed ) + { + if ( rsdp ) + printf("Found RSDP at %lx\n",(long)rsdp); + else + printf("ERROR: RSDP was not found\n"); + displayed = 1; + } + + return rsdp; +} + + struct acpi_20_rsdt *acpi_rsdt_get(unsigned char *acpi_start) { struct acpi_20_rsdp *rsdp; struct acpi_20_rsdt *rsdt; - rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); - if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) - { - printf("Bad RSDP signature\n"); + rsdp = acpi_rsdp_get(acpi_start); + if (!rsdp) return NULL; - } rsdt = (struct acpi_20_rsdt *) (acpi_start + rsdp->rsdt_address - ACPI_PHYSICAL_ADDRESS); @@ -189,12 +225,9 @@ struct acpi_20_xsdt *acpi_xsdt_get(unsigned char *acpi_start) struct acpi_20_rsdp *rsdp; struct acpi_20_xsdt *xsdt; - rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); - if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) - { - printf("Bad RSDP signature\n"); + rsdp = acpi_rsdp_get(acpi_start); + if (!rsdp) return NULL; - } xsdt = (struct acpi_20_xsdt *) (acpi_start + rsdp->xsdt_address - ACPI_PHYSICAL_ADDRESS); @@ -272,10 +305,10 @@ static unsigned char *acpi_xsdt_add_entry(unsigned char *acpi_start, /* memory below hard limit ? */ if ( (*freemem + table_size) <= limit ) { - printf("Copying SSDT entry\n"); addr = *freemem; memcpy(addr, table, table_size); - *freemem += table_size; + printf("Copied dyn. ACPI entry to %lx\n",(long)addr); + *freemem += ((table_size + 0xf) & ~0xf); acpi_xsdt_add_entry_pointer(acpi_start, addr); } -- 2.30.2